/**
 * First run detection utility
 * Detects and manages first-time application usage
 */

const fs = require('fs');
const path = require('path');
const { getConfigDir } = require('./platform');
const { getLogger } = require('../logging/logger');

const logger = getLogger();

/**
 * First run detector class
 */
class FirstRunDetector {
  /**
   * Check if this is the first run
   * @returns {Promise<boolean>} First run status
   */
  static async isFirstRun() {
    try {
      const configDir = getConfigDir();
      const firstRunFile = path.join(configDir, '.first-run');

      // If first run file doesn't exist, this is first run
      if (!fs.existsSync(firstRunFile)) {
        return true;
      }

      // Check file content to see if setup was completed
      const content = fs.readFileSync(firstRunFile, 'utf8');
      const data = JSON.parse(content || '{}');

      return !data.setupCompleted;

    } catch (error) {
      logger.warn('Failed to check first run status', error.message);
      // Assume first run if we can't determine
      return true;
    }
  }

  /**
   * Mark first run as completed
   * @param {Object} options - Options for marking completion
   * @returns {Promise<boolean>} Success status
   */
  static async markFirstRunCompleted(options = {}) {
    try {
      const configDir = getConfigDir();
      const firstRunFile = path.join(configDir, '.first-run');

      // Ensure config directory exists
      if (!fs.existsSync(configDir)) {
        fs.mkdirSync(configDir, { recursive: true });
      }

      const data = {
        setupCompleted: true,
        completedAt: new Date().toISOString(),
        version: options.version || '1.0.0',
        setupMethod: options.setupMethod || 'unknown',
        ...options // Include all other option fields
      };

      fs.writeFileSync(firstRunFile, JSON.stringify(data, null, 2));
      logger.info('First run marked as completed', data);

      return true;

    } catch (error) {
      logger.error('Failed to mark first run as completed', error.message);
      return false;
    }
  }

  /**
   * Reset first run status (for testing or re-setup)
   * @returns {Promise<boolean>} Success status
   */
  static async resetFirstRun() {
    try {
      const configDir = getConfigDir();
      const firstRunFile = path.join(configDir, '.first-run');

      if (fs.existsSync(firstRunFile)) {
        fs.rmSync(firstRunFile);
        logger.info('First run status reset');
      }

      return true;

    } catch (error) {
      logger.error('Failed to reset first run status', error.message);
      return false;
    }
  }

  /**
   * Get first run information
   * @returns {Promise<Object|null>} First run info
   */
  static async getFirstRunInfo() {
    try {
      const configDir = getConfigDir();
      const firstRunFile = path.join(configDir, '.first-run');

      if (!fs.existsSync(firstRunFile)) {
        return null;
      }

      const content = fs.readFileSync(firstRunFile, 'utf8');
      return JSON.parse(content || '{}');

    } catch (error) {
      logger.warn('Failed to get first run info', error.message);
      return null;
    }
  }

  /**
   * Check if setup should be shown based on configuration
   * @param {Object} config - Application configuration
   * @returns {Promise<boolean>} Whether to show setup
   */
  static async shouldShowSetup(config = {}) {
    // Check if force setup is enabled (highest priority)
    if (config.forceSetup === true) {
      return true;
    }

    // Check if explicitly disabled
    if (config.autoSetup === false) {
      return false;
    }

    // Check first run status
    return await FirstRunDetector.isFirstRun();
  }
}

module.exports = FirstRunDetector;